package appapi.Global;

import appapi.common.ResponseBean;
import appapi.model.ResponseModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseModel errorHandler(HttpServletRequest req, Exception e) {
        //记录异常日志
        StringBuilder sb = new StringBuilder();
        sb.append("\r\n异常访问地址：");
        sb.append(req.getRequestURI());
        sb.append("\r\n异常消息：");
        sb.append(e.getMessage());
        //logger.error(sb.toString(), e);
        ResponseModel model = new ResponseModel();
        model.setCode(-1);
        //model.setMessage(ErrorCode.ApiExecuteError.getMessage());
        model.setMessage(e.getMessage());
        //model.setCode(ErrorCode.ApiExecuteError.getCode());
        return  model;
    }

    //全局异常处理返回JSON
    @ExceptionHandler(value = BusinessException.class)
    @ResponseBody
    public ResponseModel jsonErrorHandler(HttpServletRequest req, BusinessException e) throws Exception {
        ResponseModel model = new ResponseModel();
        model.setMessage(e.getMessage());
        model.setCode(e.getCode());
        return model;
    }

    /**
     * ConstraintViolationException
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public ResponseBean ConstraintViolationExceptionHandler(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
        List<String> msgList = new ArrayList<>();
        while (iterator.hasNext()) {
            ConstraintViolation<?> cvl = iterator.next();
            msgList.add(cvl.getMessageTemplate());
        }
        return ResponseBean.fail(String.join(",",msgList));
    }
    /**
     * MethodArgumentNotValidException
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseBean MethodArgumentNotValidHandler(
            MethodArgumentNotValidException exception) {
        StringBuffer message = new StringBuffer();
        //解析原错误信息，封装后返回，此处返回非法的字段名称，原始值，错误信息
        for (FieldError error : exception.getBindingResult().getFieldErrors()) 			 {
            message.append(error.getDefaultMessage());
        }
        return ResponseBean.fail(message.toString());
    }
}
